import { IPSAppView, IPSControl, IPSEditor } from "@ibiz/dynamic-model-api";
import { onMounted } from "vue";
import { defineComponent, Ref, ref, h } from "vue";
import { App, ModelServiceUtil, PreviewData } from "../../utils";
import { Vue3JsonEditor } from 'vue3-json-editor';
import './component-demo-shell.scss';
import { Util } from "ibz-core";

const ComponentDemoShellProps = {
  type: {
    type: String,
    default: 'VIEW'
  },
  path: {
    type: String,
  },
  description: {
    type: String
  },
  height: {
    type: Number
  }
};

export const ComponentDemoShell = defineComponent({
  name: "CompoentDemoShell",
  props: ComponentDemoShellProps,
  components: {
    'vue-json-editor': Vue3JsonEditor
  },
  setup({ type, path }: any) {
    /**
     * @description 双向绑定值
     */
    let value: Ref<any> = ref(null);

    /**
     * @description 组件
     */
    const component: Ref<any> = ref({});
    /**
     * @description 模型数据
     */
    const modelData: Ref<any> = ref({});
    /**
     * @description 是否初始化完成
     */
    const isInit: Ref<boolean> = ref(false);
    /**
     * @description 模型服务工具类
     */
    const modelService = ModelServiceUtil.getInstance();
    /**
     * @description Json对象
     */
    const jsonCode: Ref<Object> = ref({});
    
    /**
     * @description uuid
     */
    const uuid: string = Util.createUUID();

    /**
     * @description 是否展示内容区
     */
    const showContent: Ref<boolean> = ref(false);
    /**
     * @description 重设屏幕大小
     */
    const resize = () => {
      const width = window.innerWidth; // 屏幕宽度
      let currentFontSize: number = 50;
      if (width <= 1920 && width > 1366) {
      } else if (width <= 1366 && width > 960) {
        currentFontSize = 36;
      } else if (width <= 960 && width > 768) {
        currentFontSize = 25;
      } else if (width <= 768) {
        currentFontSize = 16;
      }
      document.documentElement.style.fontSize = currentFontSize + 'px';
    };

    const computeComponent = () => {
      const componentService = App.getInstance().getComponentService();
      switch (type) {
        case 'VIEW':
          const view = modelData.value as IPSAppView;
          component.value = componentService.getViewTypeComponent(view?.viewType, view?.viewStyle);
          break;
        case 'CONTROL':
          const control = modelData.value as IPSControl;
          component.value = componentService.getControlComponent(control?.controlType, control?.controlStyle);
          break;
        case 'EDITOR':
          const editor = modelData.value as IPSEditor;
          component.value = componentService.getEditorComponent(editor?.editorType, editor?.editorStyle);
          break;
      }
    }

    onMounted(() => {
      modelService.getModelInstance(path, type).then(({ model, instance }) => {
        value = (instance as any).editorParams?.value || "";
        jsonCode.value = model;
        modelData.value = instance;
        computeComponent();
        isInit.value = true;
      })
      if (window && !window.onresize) {
        window.onresize = () => {
          resize();
        }
        resize();
      }
    })

    const onJsonChange = (value: any) => {
      jsonCode.value = value;
    }
    return {
      isInit,
      modelData,
      component,
      showContent,
      jsonCode,
      modelService,
      value,
      uuid,
      onJsonChange
    }
  },
  methods: {
    handleShowCodeEditor(event: any) {
      this.showContent = !this.showContent;
    },
    applyModel(event: MouseEvent) {
      event.stopPropagation();
      this.isInit = false;
      const model = this.jsonCode;
      this.modelService.refreshModel(model, this.type).then(({ model, instance }) => {
        if (instance) {
          this.modelData = instance;
          this.isInit = true;
        }
      })
    },
    handleEditorEvent(event: any) {
      this.value = event.data.value;
    }
  },
  render() {
    const style: any = {};
    if (this.height) {
      Object.assign(style, { height: this.height + 'px' });
    }
    if(this.isInit && this.component){
      return h(this.component, {
        ref: `${this.type}-${this.modelData.codeName}`,
        key: `${this.type}-${this.modelData.codeName}`,
        modelData: this.modelData,
        value: this.value,
        previewData: PreviewData.getPreviewData(),
        onEditorEvent: (event: any) => {
          this.handleEditorEvent(event);
        },
      })
    }
  }
})